//
//  lm_conf_playback_wrapper.m
//  LMConf_ios
//
//  Created by lh Authors on 16/6/19.
//  Copyright © 2016 lh. All rights reserved.
//

#import "lm_conf_playback_wrapper.h"

void CALLBACK FuncPlaybackOnPlaybackOpenCB(
                                           int result, void* clientdata) {
    ConfPlaybackWrapper* wrapper = (__bridge ConfPlaybackWrapper*)(clientdata);
    for(id obj in [wrapper delegate_array]) {
        id<ConfPlaybackWrapperDelegate> delegate = obj;
        if([delegate respondsToSelector:@selector(onPlaybackOpen:)]) {
            [delegate onPlaybackOpen:result];
        }
    }
}

void CALLBACK FuncPlaybackOnPlaybackPlayCB(
                                           int result, void* clientdata) {
    ConfPlaybackWrapper* wrapper = (__bridge ConfPlaybackWrapper*)(clientdata);
    for(id obj in [wrapper delegate_array]) {
        id<ConfPlaybackWrapperDelegate> delegate = obj;
        if([delegate respondsToSelector:@selector(onPlaybackPlay:)]) {
            [delegate onPlaybackPlay:result];
        }
    }
}

void CALLBACK FuncPlaybackOnPlaybackPauseCB(
                                            int result, void* clientdata) {
    ConfPlaybackWrapper* wrapper = (__bridge ConfPlaybackWrapper*)(clientdata);
    for(id obj in [wrapper delegate_array]) {
        id<ConfPlaybackWrapperDelegate> delegate = obj;
        if([delegate respondsToSelector:@selector(onPlaybackPause:)]) {
            [delegate onPlaybackPause:result];
        }
    }
}

void CALLBACK FuncPlaybackOnPlaybackContinueCB(
                                               int result, void* clientdata) {
    ConfPlaybackWrapper* wrapper = (__bridge ConfPlaybackWrapper*)(clientdata);
    for(id obj in [wrapper delegate_array]) {
        id<ConfPlaybackWrapperDelegate> delegate = obj;
        if([delegate respondsToSelector:@selector(onPlaybackContinue:)]) {
            [delegate onPlaybackContinue:result];
        }
    }
}

void CALLBACK FuncPlaybackOnPlaybackCompleteCB(
                                               void* clientdata) {
    ConfPlaybackWrapper* wrapper = (__bridge ConfPlaybackWrapper*)(clientdata);
    for(id obj in [wrapper delegate_array]) {
        id<ConfPlaybackWrapperDelegate> delegate = obj;
        if([delegate respondsToSelector:@selector(onPlaybackComplete)]) {
            [delegate onPlaybackComplete];
        }
    }
}

void CALLBACK FuncPlaybackOnRepairBeginCB(
                                          int error, void* clientdata) {
    ConfPlaybackWrapper* wrapper = (__bridge ConfPlaybackWrapper*)(clientdata);
    for(id obj in [wrapper delegate_array]) {
        id<ConfPlaybackWrapperDelegate> delegate = obj;
        if([delegate respondsToSelector:@selector(onRepairBegin:)]) {
            [delegate onRepairBegin:error];
        }
    }
}

void CALLBACK FuncPlaybackOnRepairEndCB(
                                        int error, void* clientdata) {
    ConfPlaybackWrapper* wrapper = (__bridge ConfPlaybackWrapper*)(clientdata);
    for(id obj in [wrapper delegate_array]) {
        id<ConfPlaybackWrapperDelegate> delegate = obj;
        if([delegate respondsToSelector:@selector(onRepairEnd:)]) {
            [delegate onRepairEnd:error];
        }
    }
}

void CALLBACK FuncPlaybackOnRepairProgressCB(
                                             int64_t currpos, int64_t duration, void* clientdata) {
    ConfPlaybackWrapper* wrapper = (__bridge ConfPlaybackWrapper*)(clientdata);
    for(id obj in [wrapper delegate_array]) {
        id<ConfPlaybackWrapperDelegate> delegate = obj;
        if([delegate respondsToSelector:@selector(onRepairProgress:duration:)]) {
            [delegate onRepairProgress:currpos duration:duration];
        }
    }
}

@implementation ConfPlaybackWrapper
@synthesize delegate_array = delegate_array_;

- (id)init {
    if ((self = [super init])) {
        c_object_ = NULL;
        delegate_array_ = [[NSMutableArray alloc] init];
    }
    return self;
}

- (id)initWithCObject:(native_object_t)c_object {
    if ((self = [super init])) {
        c_object_ = c_object;
        delegate_array_ = [[NSMutableArray alloc] init];
        
        struct ConfPlaybackCallback cb;
        memset(&cb, 0, sizeof(cb));
        cb.client_data_ = (__bridge void*)self;
        cb.OnPlaybackComplete_ = FuncPlaybackOnPlaybackCompleteCB;
        cb.OnPlaybackContinue_ = FuncPlaybackOnPlaybackContinueCB;
        cb.OnPlaybackOpen_ = FuncPlaybackOnPlaybackOpenCB;
        cb.OnPlaybackPause_ = FuncPlaybackOnPlaybackPauseCB;
        cb.OnPlaybackPlay_ = FuncPlaybackOnPlaybackPlayCB;
        cb.OnRepairBegin_ = FuncPlaybackOnRepairBeginCB;
        cb.OnRepairEnd_ = FuncPlaybackOnRepairEndCB;
        cb.OnRepairProgress_ = FuncPlaybackOnRepairProgressCB;
        lm_conf_playback_set_callback(c_object_, &cb);
    }
    return self;
}

- (void)addDelegate:(id<ConfPlaybackWrapperDelegate>)mediaplayer_delegate {
    [delegate_array_ addObject:mediaplayer_delegate];
}

- (void)removeDelegate:(id<ConfPlaybackWrapperDelegate>)mediaplayer_delegate {
    [delegate_array_ removeObject:mediaplayer_delegate];
}

- (int)startPlayback:(NSString *)file_name {
    return lm_conf_playback_StartPlayback(c_object_, [file_name UTF8String]);
}

- (int)playPlayback:(NSArray<NSString *> *)playaccounts {
    const char** ss = malloc(sizeof(const char*) * [playaccounts count]);
    int count = 0;
    for(NSString* obj in playaccounts) {
        ss[count++] = [obj UTF8String];
    }
    int ret = lm_conf_playback_PlayPlayback(c_object_, ss, count);
    free(ss);
    return ret;
}

- (int)pausePlayback {
    return lm_conf_playback_PausePlayback(c_object_);
}

- (int)continuePlayback {
    return lm_conf_playback_ContinuePlayback(c_object_);
}

- (int)stopPlayback {
    return lm_conf_playback_StopPlayback(c_object_);
}

- (int)startRepair:(NSString *)file_name {
    return lm_conf_playback_StartRepair(c_object_, [file_name UTF8String]);
}

- (int)stopRepair {
    return lm_conf_playback_StopRepair(c_object_);
}

- (BOOL)isPlaybacking {
    return !!lm_conf_playback_IsPlaybacking(c_object_);
}

- (BOOL)isRepairing {
    return !!lm_conf_playback_IsRepairing(c_object_);
}

- (int)getRecSessionCount:(enum LMRecSessionType)type {
    return lm_conf_playback_GetRecSessionCount(c_object_, type);
}

- (int)enumRecSessionInfo:(enum LMRecSessionType)type info:(struct LMRecSessionInfo*)info count:(int*)count {
    return lm_conf_playback_EnumRecSessionInfo(c_object_, type, info, count);
}

@end
